(note: this document is unicode-formatted. If it looks stupid or you're missing characters, change either your font or open it in another document reader.)

!Important Notice!
  If you used a version of this program prior to September 2008, the codeword list output is terribly terribly wrong.  (never do anything when you have a 103deg. fever...)  You will need to reconvert the text to binaries with the Aug. release of SYLKtoBIN and then convert back to SYLK to avoid any really nasty surprises.  Then, all will be well.
!end caveat!


AF-Text Conversion Tools
+-+-+-+-+-+-+-+-+-+-+-+-+
  These tools convert Animal Forest binaries into a table of text entries, and likewise convert it back.  The format used is SYLK, which isn't really the best since it doesn't accept unicode, but it is incredibly simple, free to use, can at worst be editted with notepadish-stuff, and openoffice supports it (meaning a SYLK editor is free).  This is sort of a shabby solution to the whole text issue, but it should help get some text into the game.
  The text is somewhat formatted to get around the limitations of SYLK - see the section below on the details.

  In lieu of distributing copyrighted binaries around the web, you can use the program GrabResources.exe to retrieve the text tables and binaries from both a standard and hacked Doubutsu no Mori/Animal Forest rom.  The output files are ready to be converted.

+-+-+
Usage:
  AFtoSYLK.exe		converts binary files to SYLK table
	You need a .bin file containing the text and .tbl file that sets the sizes in the same directory.  If they aren't named the same, you'll need to tell it the path.  Drag-and-drop the .bin file onto the program, or give its name at the prompt.  It automatically spits out a .slk file of the same name into the directory (hopefully).  Worst case it will spit it into either the root of the drive or your document file, depending how it feels that day.

  SYLKtoBIN.exe		converts SYLK table to AFtext binary and table
	Drag-and-drop a .slk file onto the program.  It splits it into a .bin and .tbl of the same name (again hopefully).  It expects the text entries to be in the second column, not the first, though you can use the -t switch on the command line to get around this.
	As a special note, it doesn't check if your SYLK file for content.  If you give a command too long or place quotes using "" instead of $q$q, it won't know.  It doesn't know how large each table should be or if there's a limit to data in a certain table.  You must proof your script before compiling.

NO FILENAMES CAN BEGIN WITH A "-"!  Then it will think this is a switch, not a file.  Sorry.

+-+-+
Format:
  Firstly, the SYLK file will have up to four columns by default.
	Column 1 is a list of entry numbers, in hexadecimal.  These are the same as used in-game.  Use the -L switch to omit them.
	Column 2 is the text itself.
	Column 3 is the length of the original string entry in hex.
	Column 4 will note when the text contains an invalid 7F command (usually those > 7F60)
	Column 5 will eventually note when the text contains an invalid 80 command from DnM.  They only occur in that version.
  Only column 2 is read when creating a binary from the SYLK file, so you can jot notes into any other column without screwing stuff up.  Seriously.  You can put notes in column 1 or three or 29 for that matter.

  It can't handle returns, quotes, etc.  So, must use codewords for these.  All codewords fit in brackets, and special characters like the smilies use their own code.  Also, you can write straight binary, which by default all 7F commands are shoved into.  It should have the correct size for all the 7F commands now.  All of these are CaSe SeNsItIvE.
  80 commands will always be straight binary right now.  In AF, they are skipped and assumed to be 2bytes, so processing them from DnM (the japanese AC) will more likely consist of converting them.  That isn't done yet, since getting AF working is more the issue at the moment.  So, in other words, don't bother writting 80 commands.
  All japanese is written in an ugly codeword fashion.  Sorry about that.

[] for special characters and commands
## for straight binary values
$  for certain text characters

0x2A	~	～
0x5C	+	stress, as in rupturing an artery
0x82	{	「
0x83	}	」
0x85	*	・	(middle dot- somewhat hard to tell here)

0x22	$q	"
0x2B	$h	heart
0x2F	$n	♪
0x3B	$d	bead of sweat (teardrop)
0x81	$o	。
0x84	$.	.	(fixed-width full stop)
0x90	$-	ー	
0xBF	$s	:) smiley face
0xCD	\r	return


0x00	[h-a]	あ
0x01	[h-i]	い
0x02	[h-u]	う
0x03	[h-e]	え
0x04	[h-o]	お
0x05	[h-ka]	か
0x06	[h-ki]	き
0x07	[h-ku]	く
0x08	[h-ke]	け
0x09	[h-ko]	こ
0x0A	[h-sa]	さ
0x0B	[h-shi]	し
0x0C	[h-tsu]	す
0x0D	[h-se]	せ
0x0E	[h-so]	そ
0x0F	[h-ta]	た
0x10	[h-ti]	ち
0x11	[h-tu]	つ
0x12	[h-te]	て
0x13	[h-to]	と
0x14	[h-na]	な
0x15	[h-ni]	に
0x16	[h-nu]	ぬ
0x17	[h-ne]	ね
0x18	[h-no]	の
0x19	[h-ha]	は
0x1A	[h-hi]	ひ
0x1B	[h-hu]	ふ
0x1C	[h-he]	へ
0x1D	[h-ho]	ほ
0x1E	[h-ma]	ま
0x1F	[h-mi]	み
0x23	[h-mu]	む
0x24	[h-me]	め
0x5B	[h-mo]	も
0x5D	[h-ya]	や
0x5E	[h-yu]	ゆ
0x60	[h-yo]	よ
0x7B	[h-ra]	ら
0x7C	[h-ri]	り
0x7D	[h-ru]	る
0x7E	[h-re]	れ
0x86	[k-wo]	ヲ
0x87	[ks-a]	ァ
0x88	[ks-i]	ィ
0x89	[ks-u]	ゥ
0x8A	[ks-e]	ェ
0x8B	[ks-o]	ォ
0x8C	[ks-ya]	ャ
0x8D	[ks-yu]	ュ
0x8E	[ks-yo]	ョ
0x8F	[ks-tu]	ッ
0x91	[k-a]	ア
0x92	[k-i]	イ
0x93	[k-u]	ウ
0x94	[k-e]	エ
0x95	[k-o]	オ
0x96	[k-ka]	カ
0x97	[k-ki]	キ
0x98	[k-ku]	ク
0x99	[k-ke]	ケ
0x9A	[k-ko]	コ
0x9B	[k-sa]	サ
0x9C	[k-si]	シ
0x9D	[k-su]	ス
0x9E	[k-se]	セ
0x9F	[k-so]	ソ
0xA0	[k-ta]	タ
0xA1	[k-chi]	チ
0xA2	[k-tu]	ツ
0xA3	[k-te]	テ
0xA4	[k-to]	ト
0xA5	[k-na]	ナ
0xA6	[k-ni]	ニ
0xA7	[k-nu]	ヌ
0xA8	[k-ne]	ネ
0xA9	[k-no]	ノ
0xAA	[k-ha]	ハ
0xAB	[k-hi]	ヒ
0xAC	[k-hu]	フ
0xAD	[k-he]	ヘ
0xAE	[k-ho]	ホ
0xAF	[k-ma]	マ
0xB0	[k-mi]	ミ
0xB1	[k-mu]	ム
0xB2	[k-me]	メ
0xB3	[k-mo]	モ
0xB4	[k-ya]	ヤ
0xB5	[k-yu]	ユ
0xB6	[k-yo]	ヨ
0xB7	[k-ra]	ラ
0xB8	[k-ri]	リ
0xB9	[k-ru]	ル
0xBA	[k-re]	レ
0xBB	[k-ro]	ロ
0xBC	[k-wa]	ワ
0xBD	[k-n]	ン
0xBE	[k-vu]	ヴ
0xC0	[h-ro]	ろ
0xC1	[h-wa]	わ
0xC2	[h-wo]	を
0xC3	[h-n]	ん
0xC4	[hs-a]	ぁ
0xC5	[hs-i]	ぃ
0xC6	[hs-u]	ぅ
0xC7	[hs-e]	ぇ
0xC8	[hs-o]	ぉ
0xC9	[hs-ya]	ゃ
0xCA	[hs-yu]	ゅ
0xCB	[hs-yo]	ょ
0xCC	[hs-su]	っ
0xCE	[k-ga]	ガ
0xCF	[k-gi]	ギ
0xD0	[k-gu]	グ
0xD1	[k-ge]	ゲ
0xD2	[k-go]	ゴ
0xD3	[k-za]	ザ
0xD4	[k-zi]	ジ
0xD5	[k-zu]	ズ
0xD6	[k-ze]	ゼ
0xD7	[k-zo]	ゾ
0xD8	[k-da]	ダ
0xD9	[k-di]	ヂ
0xDA	[k-du]	ヅ
0xDB	[k-de]	デ
0xDC	[k-do]	ド
0xDD	[k-ba]	バ
0xDE	[k-bi]	ビ
0xDF	[k-bu]	ブ
0xE0	[k-be]	ベ
0xE1	[k-bo]	ボ
0xE2	[k-pa]	パ
0xE3	[k-pi]	ピ
0xE4	[k-pu]	プ
0xE5	[k-pe]	ペ
0xE6	[k-po]	ポ
0xE7	[h-ga]	が
0xE8	[h-gi]	ぎ
0xE9	[h-gu]	ぐ
0xEA	[h-ge]	げ
0xEB	[h-go]	ご
0xEC	[h-za]	ざ
0xED	[h-zi]	じ
0xEE	[h-zu]	ず
0xEF	[h-ze]	ぜ
0xF0	[h-zo]	ぞ
0xF1	[h-da]	だ
0xF2	[h-di]	ぢ
0xF3	[h-du]	づ
0xF4	[h-de]	で
0xF5	[h-do]	ど
0xF6	[h-ba]	ば
0xF7	[h-bi]	び
0xF8	[h-bu]	ぶ
0xF9	[h-be]	べ
0xFA	[h-bo]	ぼ
0xFB	[h-pa]	ぱ
0xFC	[h-pi]	ぴ
0xFD	[h-pu]	ぷ
0xFE	[h-pe]	ぺ
0xFF	[h-po]	ぽ

+-+-+

7F Command Pneumonics:
  By default, all known 7F commands are output using codewords in brackets [], similiar to japanese text.  It isn't the most forgiving thing, so try to stay close to the original samples.  The aliased commands are listed below.  Commands not listed here are output in straight binary within ##.
  To try to simplify things a little, commands that accept values will have the values accepted listed below, and an example.
  !NOTE!: some commands have been removed due to programmer's stupidity

Commands:
7F00	[close]	close text window
7F01	[open]	open text window
7F02	[CLS]	clears window and returns to upper left.  Also resets text attributes.
7F03	[pause i]	pause for i hundreths of a second.  i=0<->256.
	ex. [pause 3] pauses for 3 hundreths of a second.
7F04	[wait]	places a blue advance button in the lower left, waiting for the user to press the button to advance
7F05	[color r g b]	change font color to rgb.  r is the red component, g the green, b the blue.
	ex. [color 80 80 80] makes the text grey.
7F06	[quick on]	turns quick-advance on, allowing players to press a button to instantly display text up to a pause.
7F07	[quick off]	disables quick-advance.
7F0E	[jump ####]	jumps to message_txt # given when this one is complete
7F0F	[selected 1 ####]	sets text to jump to when option 1 on a [menu] is selected ;use the list with 7F19
7F10	[selected 2 ####]	sets text to jump to when option 2 on a [menu] is selected
7F11	[selected 3 ####]	sets text to jump to when option 3 on a [menu] is selected
7F12	[selected 4 ####]	sets text to jump to when option 4 on a [menu] is selected
7F13	[rand aaaa bbbb]
7F14	[rand aaaa bbbb cccc]
7F15	[rand aaaa bbbb cccc dddd]	displays one of several text strings on the screen.
	a, b, c, and d are hex values matching the list# in the first column of the 'message_data' text bank
	ex. [rand 31A2 31A3 31A4] displays either: "I hope we'll be friends...", "I'm just glad I got to see you...", or "I get so shy sometimes..."
7F16	[menu aaaa bbbb]
7F17	[menu aaaa bbbb cccc]
7F18	[menu aaaa bbbb cccc dddd]	creates a menu with 2-4 options.
	a, b, c, and d are hex values matching the list# in the first column of the 'select_data' text bank
	ex. [menu 25 26] displays a menu with entries "That's right!" and "That's wrong!".
7F19	[jump2sel]	jump to selected text; follows a list of 7F0F-7F12
7F1A	[player]	player's name
7F1B	[speaker]	speaker's name
7F1C	[nickname]	displays a silly pet name for the player
7F1D	[year]	displays the current year
7F1E	[month]	displays the current month as a digit, ranging from 1-12
7F1F	[day] or [weekday]	displays the day as Sunday, Monday, Tuesday, etc.
7F20	[day#] or [date]	displays the day of the month, in the hacked rom as 1st - 31st
7F21	[hours]	displays current time in hours, 1-12
7F22	[mins]	displays current minutes, 0-59	note: preceeding mins or secs with a colon (ie.[hours]:[mins]) gives 2 digit time
7F23	[secs]	displays current seconds, 0-59	but on its own will give  1 digit time *in the hacked ROM only!*
7F24	[string 1]	usually displays a character's name, so [name] is also acceptable
7F25	[string 2]	string slot #2, in a predetermined color embedded in code
7F26	[string 3]	string slot #3, in a predetermined color embedded in code
7F27	[string 4]	string slot #4
7F28	[string 5]	string slot #5
7F29	[string 6]	string slot #6, in a predetermined color embedded in code
7F2A	[string 7]	string slot #7
7F2B	[string 8]	string slot #8
7F2C	[string 9]	string slot #9
7F2D	[string 10]	string slot #10
7F2E	[recall]	recalls previously selected menu option
7F2F	[town]	displays the town name
7F30	[number]	creates a random number
7F31	[string 21]	string slot #21.  [item] is also acceptable
7F32	[string 22]	string slot #22
7F33	[string 23]	string slot #23
7F34	[string 24]	string slot #24
7F35	[string 25]	string slot #25
7F36	[string 11]	string slot #11
7F37	[string 12]	string slot #12
7F38	[string 13]	string slot #13
7F39	[string 14]	string slot #14
7F3A	[string 15]	string slot #15
7F3B	[string 16]	string slot #16
7F3C	[string 17]	string slot #17
7F3D	[string 18]	string slot #18
7F3E	[string 19]	string slot #19
7F3F	[string 20]	string slot #20
7F40	[message]	inserts your personal greeting
7F50	[color #i r g b]	use the color rgb for the next i characters or until end of line.  More like a highligher, not altering the current text color.  # must be present or it treats it like 7F05.
	ex. [color #8 0 0 256] makes the next 8 characters bright blue.
7F51	[whisper on] or [whisper off]	when on, following text is not spoken in animalese but a soft typing sound.
7F54	[size1 i]	sets the font size for the next character in the text only
7F59	[sound i]	plays sound effect i.  No, I don't have a list handy.
	ex. [sound 4] is the loading sound, [sound 5] plays the springish sound effect in Resetto's dialog
7F5A	[size i]	sets the font size to i of pixels.  the larger i is, the larger the text, in theory
	ex. [size 20] sets the font to 20 pixels, like the small font used in the train on the phone
7F5E	[default]	specific to [select] menus, allows you to press B to use the default entry

  These are Animal Crossing-specific commands and will probably not be added in.  They are output so you know what you're looking at.
7F63	[`range aaaa bbbb]	randomly selects an entry in message_txt between #a and #b, inclusive
7F6A	[`interject aaaa bbbb]	similiar to the [rand]omizer commands, except this inserts the string instead of jumping to it.
7F6B	[`interject aaaa bbbb cccc]	well, this one is entirely presumption...
7F6C	[`interject aaaa bbbb cccc dddd]	as is this one...
7F71	[`isle]	name of the island in AC
7F73	[`if]	optionally displays stuff following either the [`if] or [`else] tag.
7F72	[`else]	acts as a sort of switch.  Unlike [rand], they probably stored the test value in AC.
7F77	[`selected 5 ####]	sets text to jump to when option 5 on a [menu] is selected ;use the list with 7F19
7F78	[`selected 6 ####]	sets text to jump to when option 6 on a [menu] is selected
7F79	[`menu aaaa bbbb cccc dddd eeee]		exactly like [menu] command, just accepts more fields
7F7A	[`menu aaaa bbbb cccc dddd eeee ffff]	AF has a limit of four options, AC maxes out at 6

  Three commands from Animal Crossing have been hacked into the game and now work swimmingly.
  Use them!!
7F74	[capitalize]	capitalizes first letter of next retrieved string, and forces the rest lower-case
7F75	[lowercase]	forces all letters in the next retrieved string to be lower-case
7F76	[am/pm]	displays either AM or PM.  severed from the japanese [hours] command

  These have been hacked in but do not exist in Animal Crossing
  Use them!!
7F6F	[TEXT ####]	inserts a text string.  The string number is specially-formatted:
	0xxx	select_txt
	1xxx	furnishings
	2xxx	items
	3xxx	mail_txt
	7xxx	super_txt
	8xxx	superz_txt
	9xxx	maila_txt
	Axxx	mailb_txt
	Bxxx	mailc_txt
	Cxxx	psz_txt
	Dxxx	string_txt
	Exxx	npc
	Fxxx	ps_txt
7F70	[CAPS]	capitalizes all letters in next retrieved string

  Special-case bugger here.  It was a quick way to rewrite and test all the time-checking routines.  You 'could' use it...
[TIME]	spits out the time string used by everyone who asks you the time.
	same as: [hours]:[mins] [`am/pm] on [month]\r[day#], [year]

  There's a few others as well, like [heart] works exactly like $h, because I'm silly and forget what they mean every now and then.

+-+-+

Command Line Switches:
  You can use either - or /, upper-case or lower-case for command line switches.  A screen with all the accepted switches is available if you type in either /?, -?, /H, /h, -H, or -h.

AFtoSYLK.exe switches:
/Q or -Q	quiet mode - no messages appear, and kills 7F/80 errors in the SYLK file
/L or -L	remove line numbers - be sure to cite again when converting back to a binary
/S or -S	removes the string size column from the output
/T or -T	disable text output (commands only)	all text characters are omitted.  Only 7F/80 commands appear
/C or -C	disable 7F/80 command output		displays text only.  commands are omitted without placeholders
/J or -J	disable output of japanese characters	skips all japanese characters, including「」・。.ー
/A or -A	ignore known AC-specific 7F/80 commands	skip AC-only commands, specificly 7F74 and 7F75.  They change case.
/B or -B	force binary output for 7F/80 commands	no command pneumonics are used
/N or -N	don't allow hacked commands		doesn't allow the added 7F74-76 commands
/7 or -7	uses happy pneumonics for known 7F commands (default).  Unknowns are pure binary.  Overrides binary output switch
/8 or -8	friendly 80 command aliases		to be implemented - 80xx commands aren't handled at all yet

SYLKtoBIN.exe switches:
/o or -o	create offset file, not table.  this was used with a different tool and not in-game.  debug option, in other words
/L or -L	ignore line number column.  draws text from column 1, not column 2.  only text in this column is read - rest is ignored

+-+

One last note about the source:
  Source is provided in the folder "sourcecode".  It is probably attrociously-written.  I only picked up the very minimum needed to put together silly stuff like this.  Sorry, and feel free to rewrite it as you see fit.  No need to ask.

-Zoinkity
